7. 理解 FFN(SwiGLU)

什么是 FFN(SwiGLU)?

如果说 Attention 负责“信息交换”,那么 FFN(Feed Forward Network,前馈网络)负责“信息加工”。

在现代大模型(LLaMA、Qwen、Gemma、Mistral、DeepSeek 等)里,Transformer Block 基本都是:

输入
 │
 ▼
Attention
 │
 ▼
FFN(SwiGLU)
 │
 ▼
输出

很多人会把 Attention 当成 Transformer 的核心,但实际上:

模型参数的大头往往在 FFN 里,而不是 Attention。

在 LLaMA 系列中,大约 60%~70% 的参数都在 FFN 中。


1. 先看原始 Transformer 的 FFN

2017 年《Attention Is All You Need》中的 FFN 非常简单:

FFN(x)=W2(ReLU(W1x))

流程:

x
 │
 ▼
Linear(W1)
 │
 ▼
ReLU
 │
 ▼
Linear(W2)
 │
 ▼
输出

如果模型维度:

d_model = 4096

则:

4096
 ↓
16384   (扩张4倍)
 ↓
4096

因此 FFN 又叫:

Expansion → Activation → Compression

即:

扩张
 ↓
非线性变换
 ↓
压缩

2. 为什么要改进 FFN?

研究人员发现:

ReLU

虽然简单,

但:

后来出现:

ReLU
 ↓
GELU
 ↓
GLU
 ↓
GEGLU
 ↓
SwiGLU

2020 年 Noam Shazeer(Transformer 原作者之一)发表论文:

GLU Variants Improve Transformer

专门研究:

FFN 中的激活函数能不能换掉?

结果发现:

GEGLU
SwiGLU

效果明显优于:

ReLU
GELU

3. 什么是 GLU?

理解 SwiGLU 前必须先理解 GLU。

普通 FFN

普通 FFN:

h=ReLU(xW1)

本质上:

输入
 ↓
激活
 ↓
输出

只有一条路。


GLU

GLU(Gated Linear Unit)增加了一条门控路径:

GLU(x)=(xW)σ(xV)

其中:

表示逐元素相乘。

流程:

          ┌────► Linear(V)
          │
x ────────┤
          │
          └────► Linear(W)
                    │
                    ▼
                 Sigmoid
                    │
                    ▼
            Element-wise *

可以理解成:

Value × Gate

即:

真正的信息
×
通过比例

类似:

水流 × 阀门开度

4. SwiGLU 做了什么?

SwiGLU 把 GLU 中的 Sigmoid 换成了 Swish(SiLU)。

原始 GLU:

GLU(x)=(xW)σ(xV)

SwiGLU:

SwiGLU(x)=(xV)SiLU(xW)

其中:

SiLU(z)=zσ(z)

5. 为什么叫 SwiGLU?

因为:

Swish + GLU

合起来:

SwiGLU

而:

Swish ≈ SiLU

所以代码里经常看到:

F.silu(...)

实际上就是 SwiGLU 的一部分。


6. 现代大模型里的 SwiGLU

LLaMA 的 FFN:

不是

y = down_proj(
        silu(up_proj(x))
    )

而是:

y = down_proj(
        silu(gate_proj(x))
        *
        up_proj(x)
    )

对应:

                gate_proj
                     │
                     ▼
x ─────────────────► SiLU
                     │
                     ▼
                 Gate

x ──► up_proj ─────► Value

            Gate * Value
                   │
                   ▼
             down_proj
                   │
                   ▼
                 输出

因此你会看到:

gate_proj
up_proj
down_proj

三个矩阵。

而传统 FFN 只有:

up_proj
down_proj

两个矩阵。


7. 为什么 SwiGLU 更强?

这是很多人最关心的问题。

实际上论文作者自己都承认:

他们也没有严格理论解释,只知道实验效果更好。

Pasted image 20260625162928.png

但从直觉上理解:


普通 FFN

y = GELU(Wx)

对于所有特征:

统一处理

SwiGLU

y = Value × Gate

Gate 可以动态决定:

哪些维度保留
哪些维度抑制
哪些维度放大

类似:

注意力里的权重

但是发生在 FFN 内部。

因此表达能力更强。


8. 参数为什么变成 8/3 倍?

原始 FFN:

4096
 ↓
16384
 ↓
4096

中间层:

4d

SwiGLU 有三组矩阵:

gate_proj
up_proj
down_proj

如果仍然用:

4d

参数会暴涨。

于是论文采用:

83d

代替:

4d

这样总参数量和原 FFN 基本一致。


9. 为什么 LLaMA 的 hidden_dim 是 11008?

例如:

dim = 4096

理论上:

83×4096=10922

再对齐到:

256倍数

得到:

11008

所以你会看到:

gate_proj:
4096 → 11008

up_proj:
4096 → 11008

down_proj:
11008 → 4096

这正是 LLaMA 的实现。


10. 一句话理解 SwiGLU

如果说:

Attention = 让不同Token交流

那么:

FFN = 对每个Token进行加工

而:

普通FFN = 加工一次
SwiGLU = 先生成一个“阀门(Gate)”
再决定哪些信息该通过

即:

输出 = 信息(Value) × 门控(Gate)

这相当于给 FFN 增加了一个可学习的信息筛选器,因此在几乎相同参数量下,通常比 ReLU/GELU FFN 具有更好的表达能力和训练效果。

对于学习大模型源码,可以记住一个最核心的公式:

FFNSwiGLU(x)=(SiLU(xWg)(xWu))Wd

对应代码:

gate = F.silu(gate_proj(x))
up = up_proj(x)

hidden = gate * up

out = down_proj(hidden)

这就是今天几乎所有主流 LLM(LLaMA、Qwen、Gemma、Mistral、DeepSeek)的 FFN 核心实现。

Pasted image 20260625160346.png